package er

import (
	"fmt"
	"net/http"

	"github.com/labstack/echo"
	validator "gopkg.in/go-playground/validator.v9"
)

// 自定义错误
// 包含响应状态码
type Error struct {
	StatusCode int    `json:"-"`
	Code       int    `json:"code"`
	Message    string `json:"message"`
}

func (e Error) Error() string {
	return fmt.Sprintf("%s|%d|%d", e.Message, e.Code, e.StatusCode)
}

var (
	ErrNotFound            = Error{http.StatusNotFound, 1001, "请求资源不存在"}
	ErrMethodNotAllowed    = Error{http.StatusMethodNotAllowed, 1002, "请求方法不允许"}
	ErrInternalServerError = Error{http.StatusInternalServerError, 1003, "服务内部错误"}

	ErrUnauthorized = Error{http.StatusUnauthorized, 2001, "未通过认证"}
	ErrForbidden    = Error{http.StatusForbidden, 2002, "没有请求权限"}
	ErrRateLimit    = Error{http.StatusBadRequest, 2003, "请求超出限制"}
	ErrDatabase     = Error{http.StatusBadRequest, 2010, "数据库内部错误"}
	ErrInvalidArgs  = Error{http.StatusBadRequest, 2011, "请求参数无效"}
)

// 重置echo错误处理
// 格式化错误日志为统一格式
func HTTPErrorHandler(err error, c echo.Context) {
	if v, ok := err.(Error); ok {
		c.JSON(v.StatusCode, v)
		return
	}
	// 如果是参数错误
	if _, ok := err.(validator.ValidationErrors); ok {
		c.JSON(ErrInvalidArgs.StatusCode, ErrInvalidArgs)
		return
	}
	c.JSON(http.StatusBadRequest, Error{400, 2000, err.Error()})
}

func NotFoundHandler(c echo.Context) error {
	return ErrNotFound
}

func MethodNotAllowedHandler(c echo.Context) error {
	return ErrMethodNotAllowed
}
